package view;

import android.graphics.Matrix;
import android.graphics.PointF;
import android.util.FloatMath;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;

/**
 * Created by guolchen on 2014/11/10.
 */
public class MulitPointTouchListenerEx implements OnTouchListener {
    private GestureDetector mGestureDetector = null;// 手势监听变量
    public OnZoomImageClickCallBack zoomImageClickCallBack = null;
    AnimationImageViewEx currentView = null;
    Matrix currentMatrix = new Matrix();
    Matrix savedMatrix = new Matrix();
    int currentMode = GestureMode.NONE.ordinal();

    PointF startPoint = new PointF();
    PointF midPoint = new PointF();
    float oldDist = 1f;
    boolean doubleClick = false;

    enum GestureMode {
        NONE,
        DRAG,
        ZOOM
    }

    ;

    public MulitPointTouchListenerEx() {
    }

    public MulitPointTouchListenerEx(OnZoomImageClickCallBack callback) {
        zoomImageClickCallBack = callback;
    }

    public void setZoomImageClickCallBack(OnZoomImageClickCallBack zoomImageClickCallBack) {
        this.zoomImageClickCallBack = zoomImageClickCallBack;
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (null == mGestureDetector) {
            mGestureDetector = new GestureDetector(v.getContext(), new LearnGestureListener());//注册手势监听器
            mGestureDetector.setIsLongpressEnabled(true);
        }

        float magfactor = 8.0f;
        float float_epsilon = 1e-3f;
        currentView = (AnimationImageViewEx) v;
        if ((null == currentView) || (null == currentView.getDrawable())) {
            return true;
        }
        currentView.setScaleType(AnimationImageView.ScaleType.MATRIX);
        float viewwidth = currentView.getWidth();
        float viewheight = currentView.getHeight();
        float imagewidth = currentView.getDrawable().getBounds().width();
        float imageheight = currentView.getDrawable().getBounds().height();
        float ratiox = viewwidth / imagewidth;
        float ratioy = viewheight / imageheight;
        float minratio = ratiox < ratioy ? ratiox : ratioy;
        currentView.getParent().getParent().requestDisallowInterceptTouchEvent(true);

        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                currentMatrix.set(currentView.getImageMatrix());
                savedMatrix.set(currentMatrix);
                startPoint.set(event.getX(), event.getY());
                currentMode = GestureMode.DRAG.ordinal();
                break;

            case MotionEvent.ACTION_POINTER_DOWN:
                oldDist = spacing(event);
                if (oldDist > 10f) {
                    savedMatrix.set(currentMatrix);
                    midPoint(midPoint, event);
                    currentMode = GestureMode.ZOOM.ordinal();
                }
                break;

            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_POINTER_UP:
                if (doubleClick) {
                    //doubleClick = false;
                } else {
                    if (currentMode == GestureMode.DRAG.ordinal()) {
                        currentMatrix.set(savedMatrix);
                        currentMatrix.postTranslate(event.getX() - startPoint.x, event.getY()
                                - startPoint.y);
                        float[] values = new float[9];
                        currentMatrix.getValues(values);
                        float curwidth = values[0] * imagewidth;
                        float curheight = values[0] * imageheight;
                        float startx = values[2];
                        float starty = values[5];
                        float endx = startx + curwidth;
                        float endy = starty + curheight;
                        if ((startx < 0 && endx < viewwidth) ||
                                (startx > 0 && endx > viewwidth) ||
                                (starty < 0 && endy < viewheight) ||
                                (starty > 0 && endy > viewheight)) {
                            //currentMatrix.set(savedMatrix);
                        }
                    } else if (currentMode == GestureMode.ZOOM.ordinal()) {
                        currentMatrix.set(savedMatrix);
                        float newdist = spacing(event);
                        float scale = newdist / oldDist;
                        currentMatrix.postScale(scale, scale, midPoint.x, midPoint.y);
                        float[] values = new float[9];
                        currentMatrix.getValues(values);
                        float curwidth = values[0] * imagewidth;
                        float curheight = values[0] * imageheight;
                        float startx = values[2];
                        float starty = values[5];
                        float endx = startx + curwidth;
                        float endy = starty + curheight;
                        //放大后中断pager的事件，否则启用
                        if ((startx < 0 && endx < viewwidth) ||
                                (startx > 0 && endx > viewwidth) ||
                                (starty < 0 && endy < viewheight) ||
                                (starty > 0 && endy > viewheight) ||
                                (values[0] < minratio)) {
                            //currentMatrix.set(savedMatrix);
                            float transx, transy;
                            if (ratiox < ratioy) {
                                transx = 0;
                                transy = (viewheight - ratiox * imageheight) / 2;
                            } else {
                                transx = (viewwidth - ratioy * imagewidth) / 2;
                                transy = 0;
                            }
                            values[0] = values[4] = minratio;
                            values[2] = transx;
                            values[5] = transy;
                            currentMatrix.setValues(values);
                        }

                        if (values[0] > magfactor * minratio) {
                            //currentMatrix.set(savedMatrix);
                        }
                    }
                }
                currentMode = GestureMode.NONE.ordinal();
                break;

            case MotionEvent.ACTION_MOVE:
                if (currentMode == GestureMode.DRAG.ordinal()) {
                    currentMatrix.set(savedMatrix);
                    currentMatrix.postTranslate(event.getX() - startPoint.x, event.getY()
                            - startPoint.y);
                    //如果拖动过程中超出了边界，启动翻页的事件
                    float[] values = new float[9];
                    currentMatrix.getValues(values);
                    float curwidth = values[0] * imagewidth;
                    float curheight = values[0] * imageheight;
                    float startx = values[2];
                    float endx = startx + curwidth;
                    float starty = values[5];
                    float endy = starty + curheight;
                    if (startx > 0 || endx < viewwidth) {
                        currentView.getParent().getParent().requestDisallowInterceptTouchEvent(false);
                    }
                } else if (currentMode == GestureMode.ZOOM.ordinal()) {
                    float newdist = spacing(event);
                    if (newdist > 10f) {
                        currentMatrix.set(savedMatrix);
                        float scale = newdist / oldDist;
                        currentMatrix.postScale(scale, scale, midPoint.x, midPoint.y);
                    }
                }
                break;
            case MotionEvent.ACTION_CANCEL:
                currentMatrix.set(savedMatrix);
                break;
        }
        if (doubleClick) {
            doubleClick = false;
        } else {
            currentView.setImageMatrix(currentMatrix);
        }
        mGestureDetector.onTouchEvent(event);// 执行双击和长按手势操作
        return true;
    }

    private float spacing(MotionEvent event) {
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        //return FloatMath.sqrt(x * x + y * y);
        return 1.0f;
    }

    private void midPoint(PointF point, MotionEvent event) {
        float x = event.getX(0) + event.getX(1);
        float y = event.getY(0) + event.getY(1);
        point.set(x / 2, y / 2);
    }


    //手势监听器
    class LearnGestureListener extends GestureDetector.SimpleOnGestureListener {
        /* 双击操作 */
        @Override
        public boolean onDoubleTap(MotionEvent arg0) {
            PointF doublePt = new PointF(arg0.getX(0), arg0.getY(0));
            //zoomImageClickCallBack.OnDoubleClickResponse(doublePt);
            doubleClick = true;
            return true;
        }

        /* 长按操作 */
        @Override
        public void onLongPress(MotionEvent ev) {
            PointF doublePt = new PointF(ev.getX(0), ev.getY(0));
            if (null != zoomImageClickCallBack) {
                //zoomImageClickCallBack.OnLongClickResponse(doublePt);
            }
        }

        @Override
        public boolean onSingleTapConfirmed(MotionEvent ev) {
            PointF doublePt = new PointF(ev.getX(0), ev.getY(0));
            if (null != zoomImageClickCallBack) {
                //zoomImageClickCallBack.OnSingleTapConfirmed(doublePt);
            }
            return true;
        }
    }
}